package com.ljw.security.distributedsecurityorder.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ljw.security.distributedsecurityorder.common.EncryptUtil;
import com.ljw.security.distributedsecurityorder.common.UserDTO;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @FileName TokenAuthenticationFilter
 * @Description TODO  定义filter，拦截来自网关的token，解析用户身份信息，并形成Spring Security的Authentication对象
 * 还是三个步骤：
 * 1.解析token
 * 2.新建并填充authentication
 * 3.将authentication保存进安全上下文
 * 剩下的事儿就交给Spring Security好了。
 * @Author ljw
 * @Date 2020/11/24 21:59
 * @Version 1.0
 */
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String token = httpServletRequest.getHeader("json-token");
        if (token != null){
            //1.解析token
            String json = EncryptUtil.decodeUTF8StringBase64(token);
            JSONObject userJson = JSON.parseObject(json);
            /*UserDTO user = new UserDTO();
            user.setUsername(userJson.getString("principal"));*/
            //取出用户身份信息
            String principal = userJson.getString("principal");
            //将json转成对象
            UserDTO user = JSON.parseObject(principal, UserDTO.class);
            JSONArray authoritiesArray = userJson.getJSONArray("authorities");
            String [] authorities = authoritiesArray.toArray( new String[authoritiesArray.size()]);
            //2.新建并填充authentication
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( user, null, AuthorityUtils.createAuthorityList(authorities));
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails( httpServletRequest));
            //3.将authentication保存进安全上下文
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
